package XishiBackend.controllers.microsite;

import java.util.*;

import javax.servlet.http.HttpServletRequest;

import net.sf.json.JSONObject;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import XishiBackend.base.Constant;
import XishiBackend.base.Json;
import XishiBackend.base.Message;
import XishiBackend.base.TimeUtil;
import XishiBackend.models.entity.Admin;
import XishiBackend.models.entity.Order;
import XishiBackend.models.entity.Restaurant;
import XishiBackend.models.entity.User;
import XishiBackend.services.microsite.MicrositeOrderService;

@RestController
@EnableAutoConfiguration
@RequestMapping("/microsite/order")
public class MicrositeOrderController {
    
    @Autowired
    private MicrositeOrderService oS;
    
    @RequestMapping(value = "/userorderlist",method=RequestMethod.POST)
    public String userorderlist(@RequestParam("sig") String sig,@RequestParam("userId") long userId) {
        List<Order> orderList = oS.findByUserIdOrderByCreateTimeDesc(userId);
        return Json.format(0, "获取用户订单成功", oS.orderList(orderList));
    }
    @RequestMapping(value = "/orderdetail", method=RequestMethod.POST)
    public String orderdetail(@RequestParam("sig") String sig,@RequestParam("orderId") long orderId) {
        Order o = oS.findOne(orderId);
        if(o == null) {
            return Json.format(1, "获取订单详情失败，订单不存在");
        }
        return Json.format(0, "获取订单详情成功", oS.orderOptimization(o));
    }
    
    @RequestMapping(value = "/orderstatus",method=RequestMethod.POST)
    public String orderstatus(@RequestParam("sig") String sig) {
        Map<String,String> osmap = new HashMap<String,String>();
        for(int i = 0;i < Constant.ORDER_STATUS.length;i++) {
            osmap.put("" + i, Constant.ORDER_STATUS[i]);
        }
        return Json.format(0, "获取订单状态分类成功", osmap);
    }
    
    @RequestMapping(value = "/paytype",method=RequestMethod.POST)
    public String paytype(@RequestParam("sig") String sig) {
        Map<String,String> ptmap = new HashMap<String,String>();
        for(int i = 0;i < Constant.PAY_TYPE.length;i++) {
            ptmap.put("" + i, Constant.PAY_TYPE[i]);
        }
        return Json.format(0, "获取支付方式分类成功", ptmap);
    }
    
    @RequestMapping(value = "/commitorder",method=RequestMethod.POST)
    public String commitorder(@RequestParam("sig") String sig,HttpServletRequest request, @RequestParam("userId") long userId,@RequestParam("totalPrice") float totalPrice,
            @RequestParam("voucherId") long voucherId, @RequestParam("remark") String remark, 
            @RequestParam("orderType") int orderType, @RequestParam("dishes") String buyCar, 
            @RequestParam("deliveryTime") String deliveryTime){
        
        //通过user获取必要信息，清空购物车
        User u = oS.findUserByUserId(userId);
        if(u == null) {
            return Json.format(1, "提交订单失败，用户不存在");
        }
        
//        String dishes = u.getBuyCar();
        String dishes = buyCar;
        
        long distributionId = u.getDistributionId();
        //随机分配订单至店铺
        long restaurantId = 0;
        List<Restaurant> rList = oS.findRestaurantByDistributionId(distributionId);
        if(rList.isEmpty()) {
            return Json.format(7, "提交订单失败，取餐点没有相关联的店铺");
        }
        int index = (int) Math.floor(Math.random() * rList.size());
        restaurantId = rList.get(index).getId();
        
//        u.setBuyCar("{}");
//        if(!uR.save(u).getBuyCar().equals("{}")) {
//            return Json.format(2,"提交订单失败，保存购物车失败");
//        }
        
        //计算菜品分类统计
        Map<String,Integer> dishesType = new HashMap<String,Integer>(); 
        Map<Long, Long> dtMap = oS.getDishesTypeMap();
        Map<String, Integer> dMap = Json.decodeCar(dishes);
        for(String key:dMap.keySet()) {
            String k = "" + dtMap.get(Long.parseLong(key));        //获取菜品分类Id
            if(dishesType.containsKey(k)) {
                dishesType.put(k, dishesType.get(k) + dMap.get(key));
            }
            else {
                dishesType.put(k, dMap.get(key));
            }
        }
        
        Order o = new Order(dishes,Json.encodeCar(dishesType),totalPrice,voucherId,remark,restaurantId,distributionId,
                Constant.NEW, u.getId(), u.getTel(), orderType, Constant.NOT_PAID, deliveryTime);
        //以下为各种支付方式的处理
        if(orderType == Constant.COD) {
            //如果是货到付款订单，就标志为已付过款，并跳过支付直接返回
            o.setHasPaid(Constant.PAID);
            long orderId = oS.save(o);
            if(orderId != 0) {
                o.setOrderId(orderId);
                //推送至android后台
                pushMessage(restaurantId, o);
                Map<String, Object> r = new HashMap<String, Object>();
                r.put("takeNo", o.getTakeNo());
                r.put("orderId", o.getOrderId());
                return Json.format(0, "提交订单成功", r);
            }
            else {
                return Json.format(3, "提交订单失败，新建订单失败");
            }
        }
        else if(orderType == Constant.WX_ONLINE){
            //微信支付就调用微信的统一支付接口，并将返回值返回给前端
            long orderId = oS.save(o);
            if(orderId != 0) {
                o.setOrderId(orderId);
                String resp = Constant.wxUnifiedorder(o, u.getOpenId(), request.getRemoteAddr());
                System.out.println(resp);
                JSONObject json = JSONObject.fromObject(resp);
                if(json.getString("return_code").equals("SUCCESS") && 
                    json.getString("result_code").equals("SUCCESS")) {
                    //保存prepayId
                    o.setPrepayId(json.getString("prepay_id"));
                    oS.save(o);
                    //返回orderId和取餐号
                    Map<String, Object> r = new HashMap<String, Object>();
                    r.put("takeNo", o.getTakeNo());
                    r.put("orderId", o.getOrderId());
                    r.put("resp", resp);
                    return Json.format(0, "提交订单成功", r);
                }
                else {
                    return Json.format(4, "提交订单失败，调用微信接口失败");
                }
            }
            else {
                return Json.format(3, "提交订单失败，新建订单失败");
            }
        }
        else if(orderType == Constant.USER_MONEY) {
            if(u.getMoney() < o.getTotalPrice()) {
                return Json.format(5, "提交订单失败，用户余额不足");
            }
            long orderId = oS.userMoneyPay(o);
            if(orderId != 0) {
                o.setOrderId(orderId);
                //推送至android后台
                pushMessage(restaurantId, o);
                
                Map<String, Object> r = new HashMap<String, Object>();
                r.put("takeNo", o.getTakeNo());
                r.put("orderId", o.getOrderId());
                return Json.format(0, "提交订单成功", r);
            }
            else {
                return Json.format(3, "提交订单失败，新建订单失败");
            }
        }
        return Json.format(6, "提交订单失败，未知订单支付方式");
    }
    
    @RequestMapping(value = "/cancelorder",method=RequestMethod.POST)
    public String cancelorder(@RequestParam("sig") String sig,@RequestParam("orderId") long orderId) {
        Order o = oS.findOne(orderId);
        if(o == null) {
            return Json.format(1,"取消订单失败，订单不存在");
        }
        if(o.getStatus() != Constant.NEW) {
            return Json.format(2, "取消订单失败，订单已经开始配送");
        }
        
        o.setUpdateTime(TimeUtil.now());
        o.setStatus(Constant.CANCEL);
        o.setOperatorId(0);
        o.setHasPaid(Constant.NOT_PAID);
        o.setCancelRemark(Constant.USER_CANCEL);
//        if(o.getOrderType() == Constant.WX_ONLINE && o.isHasPaid() == Constant.NOT_PAID) {
//            //如果是没有付过款的微信订单，就调用关闭订单接口
//            String resp = Constant.wxCloseOrder(o);
//            JSONObject json = JSONObject.fromObject(resp);
//            if(!json.getString("return_code").equals("SUCCESS")) {
//                System.out.println(json.getString("return_msg")+":"+o.getOrderId());
//            }
//        }
        if(oS.save(o) != 0) {
            return Json.format(0, "取消订单成功");
        }
        else {
            return Json.format(3, "取消订单失败，订单状态修改失败");
        }
    }

    @RequestMapping(value = "/reorder",method=RequestMethod.POST)
    public String reorder(@RequestParam("sig") String sig,HttpServletRequest request, @RequestParam("orderId") long orderId) {
        Order o = oS.findOne(orderId);
        if(o == null) {
            return Json.format(1,"重新下单失败，订单不存在");
        }
        if(o.getStatus() != Constant.CANCEL) {
            return Json.format(2, "重新下单失败，不是已取消的订单");
        }
        
        o.setUpdateTime(TimeUtil.now());
        o.setStatus(Constant.NEW);
        o.setOperatorId(0);
        if(oS.save(o) == 0) {
            return Json.format(3, "重新下单失败，订单状态修改失败");
        }
        else {
            User u = oS.findUserByUserId(o.getUserId());
            if(o.isHasPaid()) {
                //如果已经付过款，就不调用微信的接口
                //推送至android后台
//                for(Admin a:oS.findAdminByRestaurantId(u.getRestaurantId())) {
//                    Message.sendPushMessage(a.getDeviceToken(), o.toString());
//                }
                Map<String, Object> r = new HashMap<String, Object>();
                r.put("takeNo", o.getTakeNo());
                return Json.format(0, "提交订单成功", r);
            }
            String resp = Constant.wxUnifiedorder(o, u.getOpenId(), request.getRemoteAddr());
            JSONObject json = JSONObject.fromObject(Json.xml2json(resp));
            if(json.getString("return_code").equals("SUCCESS") && 
                json.getString("result_code").equals("SUCCESS")) {
                //推送至android后台
                for(Admin a:oS.findAdminByRestaurantId(o.getRestaurantId())) {
                    Message.sendPushMessage(a.getDeviceToken(), o.toString());
                }
                Map<String, Object> r = new HashMap<String, Object>();
                r.put("takeNo", o.getTakeNo());
                r.put("resp", resp);
                return Json.format(0, "重新下单", r);
            }
            else {
                return Json.format(4, "重新下单，调用微信接口失败");
            }
        }
    }
    
    //接受微信下单反馈的action
    @RequestMapping(value = "/pay")
    public String pay(@RequestBody String xml) {
        Map<String, Object> r = new HashMap<String, Object>();
        JSONObject json = JSONObject.fromObject(Json.xml2json(xml));
        if(json.getString("return_code").equals("SUCCESS") && 
                json.getString("result_code").equals("SUCCESS")) {
            long orderId = json.getLong("out_trade_no");
            Order o = oS.findOne(orderId);
            o.setHasPaid(Constant.PAID);
            o.setUpdateTime(TimeUtil.now());
            if(oS.save(o) != 0) {
                pushMessage(o.getRestaurantId(), o);    //推送订单
                r.put("return_code", "SUCCESS");
                r.put("return_msg", "OK");
                return Json.json2xml(r);
            }
            else {
                r.put("return_code", "FAIL");
                r.put("return_msg", "保存订单信息失败");
                return Json.json2xml(r);
            }
        }
        else {
            r.put("return_code", "FAIL");
            r.put("return_msg", "支付失败");
            return Json.json2xml(r);
        }
    }
    
    private void pushMessage(long restaurantId, Order o) {
        for(Admin a:oS.findAdminByRestaurantId(restaurantId)) {
            boolean tokenExpire = TimeUtil.string2Date(a.getLastLoginTime()).getTime() + 7 * 24 * 3600 * 1000 < new Date().getTime();     //7天令牌保存时间
            if(!tokenExpire && !a.getDeviceToken().equals("")) {
                Message.sendPushMessage(a.getDeviceToken(), Json.encode(oS.orderOptimization(o)));
            }
        }
    }
}
